#!/usr/bin/env node


// Node CLI 应用入口文件必须要有这样的文件头
// 如果是 Linux 或者 macOS 系统下还需要修改此文件的读写权限为 755
// 具体就是通过 chmod 755 cli.js 实现修改

const fs = require('fs')    // 文件读写
const path = require('path')    // 路径获取
const inquirer = require('inquirer')    //命令行用户交互
const ejs = require('ejs')  // 模板引擎


// 脚手架的工作过程：启动 => 命令行询问用户问题 => 结合问题答案+模板 => 生成结构文件

inquirer.prompt([
    {
        type: 'input',
        name: 'name',
        message: '请输入项目名称(\'\')'
    },
    {
        type: 'input',
        name: 'version',
        message: '请输入项目版本号(1.0.0)'
    },
    {
        type: 'input',
        name: 'description',
        message: '请输入项目备注(\'\')'
    },
    {
        type: 'input',
        name: 'author',
        message: '请输入作者名称(\'\')'
    }
])
.then(anwsers => {
    // anwsers: { name: "xxx" } //anwsers返回一个结果对象

    // 模板目录绝对路径
    const tmplDir = path.join(__dirname, 'templates')
    // 目标目录
    const destDir = process.cwd()

    // 读取目录下所有文件
    let readFiles = (dir) => {
        return new Promise((resolve, reject)=>{
            // 参数1：目录路径
            // 参数2：回调函数（错误对象，files为文件相对路径组成的数组）
            fs.readdir(dir, (err, files) => {
                if (err) reject(err)
                resolve(files)
            })
        })
    }

    // 处理模板文件
    let ejsRender = (file) => {
        return new Promise((resolve, reject)=>{
            // 模板文件绝对路径
            let dir = path.join(tmplDir, file)
            // 参数1：文件路径
            // 参数2：数据对象
            // 参数3：回调函数（错误对象，渲染后的新文件）
            ejs.renderFile(dir, anwsers, (err, result) => {
                if (err) reject(err)
                resolve(result)
            })
        })
    }


    // 1、先读取目录下所有文件
    // 2、使用ejs渲染所有模板
    // 3、再将新文件写到目标路径
    readFiles(tmplDir).then((files)=>{
        files.forEach(file => {
            ejsRender(file).then((result)=>{
                // 目标文件绝对路径，file其实是文件相对路径
                let fileDestDir = path.join(destDir, file)
                // 将结果写入目标文件路径
                // 参数1：文件绝对路径
                // 参数2：渲染后新文件
                fs.writeFileSync(fileDestDir, result)
            },throwError)
        })

    },throwError)
})

/**
 * 错误处理函数
 * @param {*错误对象} error 
 */
function throwError(error){
    throw error
}


